package com.dissertation.service.impl;

import com.dissertation.pojo.UserStatisticsBean;
import com.dissertation.pojo.UserStatisticsWrapBean;
import com.dissertation.service.IStatisticsByUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserStatisticsGroup implements IStatisticsByUser {

    @Autowired
    MongoTemplate template;

    private AggregationOperation createMatch( String categoryTreeName ) {
        return match( Criteria.where( "deleted" ).is( false )
                .and( "categoryTreeName" ).is( categoryTreeName ) );
    }


    @Override
    public List<UserStatisticsWrapBean> getAllUserCount( String categoryTreeName ) {
        Aggregation aggregation = Aggregation.newAggregation(
                createMatch( categoryTreeName ),
                unwind( "relative" ),
                group( "relative" ).count().as( "count" )
                .first( "relative" ).as( "userName" )
                .first( "categoryLeafName" ).as( "categoryLeafName" )
        );
        return exchange( template.aggregate( aggregation, "assets", UserStatisticsBean.class ).getMappedResults() );
    }

    @Override
    public List<UserStatisticsWrapBean> getParticipantUserCount( String categoryTreeName ) {
        Aggregation aggregation = Aggregation.newAggregation(
                createMatch( categoryTreeName ),
                unwind( "participantIds" ),
                group( "participantIds", "categoryLeafName" ).count().as( "count" )
                 .first( "participantIds" ).as( "userName" )
                .first( "categoryLeafName" ).as( "categoryLeafName" )

        );
        List<UserStatisticsBean> userStatisticsBeans = template.aggregate( aggregation, "assets",
                UserStatisticsBean.class ).getMappedResults();
        return exchange( userStatisticsBeans );
    }


    private List<UserStatisticsWrapBean> exchange( List<UserStatisticsBean> userStatisticsBeans ) {
        return userStatisticsBeans.stream()
                .collect( Collectors.groupingBy( UserStatisticsBean::getUserName
                ) ).entrySet().stream()
                .map( entry -> new UserStatisticsWrapBean( entry.getKey(), entry.getValue() ) )
                .collect( Collectors.toList() );
    }


    @Override
    public List<UserStatisticsWrapBean> getAuthorUserCount( String categoryTreeName ) {
        Aggregation aggregation = Aggregation.newAggregation(
                createMatch( categoryTreeName ),
                group( "author", "categoryLeafName" ).count().as( "count" )
                        .first( "categoryLeafName" ).as( "categoryLeafName" )
                        .first( "author" ).as( "userName" )
        );
        return exchange( template.aggregate( aggregation, "assets", UserStatisticsBean.class )
                .getMappedResults() );
    }
}
